package hu.pixelesztergalyos.gui;

import hu.pixelesztergalyos.continuity.Character;
import hu.pixelesztergalyos.continuity.Game;
import hu.pixelesztergalyos.continuity.GameState;
import hu.pixelesztergalyos.continuity.Gate;
import hu.pixelesztergalyos.continuity.Key;
import hu.pixelesztergalyos.continuity.Level;
import hu.pixelesztergalyos.continuity.Mosaic;
import hu.pixelesztergalyos.continuity.MosaicElement;
import hu.pixelesztergalyos.continuity.ViewState;
//import hu.pixelesztergalyos.gui.Controller.KilepesActionListener;

import java.awt.BorderLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class Controller {
	public static Game game;    // initiating game entity
	public static View view;    // initiating view entity
	public static Timer timer;  // initiating timer entity

	public eventClass handler;
	public FolytatasActionListener continueHandler;
	public KilepesActionListener exitHandler;
	public FomenuActionListener mainMenuHandler;
	public Folyatatas_pMenuActionListerner goOnHandler;

	public Controller() {
		handler = new eventClass();
		continueHandler = new FolytatasActionListener();
		exitHandler = new KilepesActionListener();
		mainMenuHandler = new FomenuActionListener();
		goOnHandler= new Folyatatas_pMenuActionListerner();
	}

	private class eventClass implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			try {
			FileWriter fw = new FileWriter("levelID.txt");
			PrintWriter pw = new PrintWriter(fw);
			
			
				game.loadLevel("continuity_L001.xml");
				timer.gs = GameState.PLAYING;
				
				pw.println("1");

				view.PMenupanel.setVisible(false);
				view.MMenupanel.setVisible(false);

				view.mosPanel.setVisible(true);
				view.frame.getContentPane().add(view.mosPanel, BorderLayout.CENTER);
				view.frame.setSize(780, 480);

				timer.enable();
				pw.close();
				view.frame.requestFocusInWindow();
			} catch (Exception e1) {
				e1.printStackTrace();
			}
		}
	}
	
	private class FolytatasActionListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			try{
				FileReader fr = new FileReader("levelID.txt");
				BufferedReader br = new BufferedReader(fr);
				
				String levelIdStr = br.readLine();
				int levelId = Integer.parseInt(levelIdStr);
			
				game.loadLevel("continuity_L" + String.format("%03d", levelId) + ".xml");

				
				timer.gs = GameState.PLAYING;
				
				view.PMenupanel.setVisible(false);
				view.MMenupanel.setVisible(false);

				view.mosPanel.setVisible(true);
				view.frame.getContentPane().add(view.mosPanel, BorderLayout.CENTER);
				view.frame.setSize(780, 480);

				timer.enable();
				br.close();
				view.frame.requestFocusInWindow();
		
			}catch(Exception exc){
				exc.printStackTrace();
			}
		}
	}
	
	private class KilepesActionListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			System.exit(0);
		}
	}
		

	private class FomenuActionListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			timer.gs = GameState.MAINMENU;
			timer.enabled = false;
			view.frame.setSize(800,600);
			view.renderMainMenu();
			view.frame.requestFocusInWindow();
		}
	}
	
	private class Folyatatas_pMenuActionListerner implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			timer.gs = GameState.PLAYING;
			view.PMenupanel.setVisible(false);
			view.MMenupanel.setVisible(false);
			view.mosPanel.setVisible(true);
			view.frame.setSize(780,480);
			view.frame.getContentPane().add(view.mosPanel, BorderLayout.CENTER);
			timer.enable();
			view.frame.requestFocusInWindow();
			
		}
	}
   
   
  // main(): application main function
	public static void main(String[] args) throws InterruptedException, IOException {
		game = new Game();                // instantiating new game
		Controller c = new Controller();  // instantiating new controller
		game.c = c;                       // setting game controller to newly created controller
		view = new View(c);               // instantiating new view with connected controller
		timer = new Timer();              // instantiating new timer
		timer.owner = game;               // setting timer to connect with game entity
		timer.view = view;                // setting timer to connect with view entity
    timer.gs = GameState.MAINMENU;    // setting timer gamestate to MainMenu (timer: disabled)

		view.frame.addKeyListener(new KeyListener() {
			@Override
			public void keyPressed(KeyEvent arg0) {
				if (arg0.getKeyChar() != ' ')
				{
					if (view.vs == ViewState.MOSAIC)
					game.ks[arg0.getKeyCode()] = true;
					else
					{
						game.ks[arg0.getKeyCode()] = true;
						try {
							timer.enabled = false;
							Thread.currentThread().sleep(50);
							timer.enable();
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				}
			}

			@Override
			public void keyReleased(KeyEvent arg0) {
				game.ks[arg0.getKeyCode()] = false;
			}

			@Override
			public void keyTyped(KeyEvent arg0) {
				if (arg0.getKeyChar() == ' ')
					game.ks[KeyEvent.VK_SPACE] = true;				
				if (arg0.getKeyChar() == KeyEvent.VK_ESCAPE)
				{
					if (timer.gs == GameState.PLAYING)
						{
						timer.gs = GameState.PAUSEMENU;
						timer.enabled = false;
						view.frame.setSize(800,600);
						view.renderPauseMenu();
						return;
						}
					if (timer.gs == GameState.PAUSEMENU) 
						{
						timer.gs = GameState.PLAYING;
						view.PMenupanel.setVisible(false);
						view.MMenupanel.setVisible(false);
						view.mosPanel.setVisible(true);
						view.frame.setSize(780,480);
						view.frame.getContentPane().add(view.mosPanel, BorderLayout.CENTER);
						timer.enable();
						return;
						}
				}
			}
		});

		while (true) // Haxxed "onidle"
		{
			timer.checkTime();
		}
	}

	public void setModelData(Character c1, Character c2, Gate g, Key k, Mosaic[][] me, Point p) {
		view.setModelData(c1, c2, g, k, me, p);
	}
}
